```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring Boot 事件机制详解 | 技术小馆</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background-color: #f8f9fa;
            color: #333;
        }
        .serif {
            font-family: 'Noto Serif SC', serif;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .code-block {
            background-color: #2d2d2d;
            color: #f8f8f2;
            border-radius: 0.375rem;
            overflow-x: auto;
        }
        .timeline-item:before {
            content: '';
            position: absolute;
            left: -8px;
            top: 0;
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background: #6e8efb;
            box-shadow: 0 0 0 4px rgba(110, 142, 251, 0.2);
        }
    </style>
</head>
<body class="antialiased">
    <!-- Hero Section -->
    <div class="hero-gradient text-white py-20 px-4 sm:px-6 lg:px-8">
        <div class="max-w-5xl mx-auto">
            <div class="flex items-center mb-6">
                <span class="bg-white text-indigo-600 px-3 py-1 rounded-full text-sm font-semibold mr-3">Spring Boot</span>
                <span class="text-indigo-100">事件驱动架构</span>
            </div>
            <h1 class="serif text-4xl md:text-5xl font-bold leading-tight mb-6">Spring Boot 事件机制深度解析</h1>
            <p class="text-xl text-indigo-100 max-w-3xl mb-8">理解Spring应用中的发布-订阅模式，掌握松耦合通信的艺术</p>
            <div class="flex flex-wrap gap-4">
                <a href="#overview" class="bg-white text-indigo-600 hover:bg-indigo-50 px-6 py-3 rounded-lg font-medium transition-colors duration-300">
                    <i class="fas fa-book-open mr-2"></i>核心概念
                </a>
                <a href="#timeline" class="bg-indigo-700 hover:bg-indigo-600 text-white px-6 py-3 rounded-lg font-medium transition-colors duration-300">
                    <i class="fas fa-clock mr-2"></i>生命周期事件
                </a>
                <a href="#custom" class="border-2 border-white hover:bg-white hover:text-indigo-600 text-white px-6 py-3 rounded-lg font-medium transition-colors duration-300">
                    <i class="fas fa-code mr-2"></i>自定义实现
                </a>
            </div>
        </div>
    </div>

    <!-- Main Content -->
    <div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
        <!-- Overview Section -->
        <section id="overview" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-12 h-1 bg-indigo-500 mr-4"></div>
                <h2 class="serif text-3xl font-bold">事件机制概述</h2>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-12">
                <div class="bg-white p-8 rounded-xl shadow-md card-hover">
                    <div class="text-indigo-500 mb-4">
                        <i class="fas fa-bullhorn text-4xl"></i>
                    </div>
                    <h3 class="serif text-xl font-bold mb-4">发布-订阅模式</h3>
                    <p class="text-gray-700 leading-relaxed">Spring Boot 的事件机制是基于 Spring 框架的应用上下文事件实现的，采用发布-订阅模式实现组件间松耦合通信。一个组件发布事件，其他感兴趣的组件通过监听这些事件来做出相应处理。</p>
                </div>
                <div class="bg-white p-8 rounded-xl shadow-md card-hover">
                    <div class="text-indigo-500 mb-4">
                        <i class="fas fa-project-diagram text-4xl"></i>
                    </div>
                    <h3 class="serif text-xl font-bold mb-4">核心组件</h3>
                    <ul class="space-y-2 text-gray-700">
                        <li class="flex items-start">
                            <i class="fas fa-circle text-xs text-indigo-500 mt-1 mr-2"></i>
                            <span><strong>事件(Event)</strong> - 继承自ApplicationEvent类的对象</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-circle text-xs text-indigo-500 mt-1 mr-2"></i>
                            <span><strong>监听器(Listener)</strong> - 实现ApplicationListener接口的组件</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-circle text-xs text-indigo-500 mt-1 mr-2"></i>
                            <span><strong>发布者(Publisher)</strong> - ApplicationEventPublisher接口实现</span>
                        </li>
                    </ul>
                </div>
            </div>

            <!-- Visualization -->
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-12">
                <div class="p-6 border-b border-gray-200">
                    <h3 class="serif text-xl font-bold">事件机制工作流程</h3>
                </div>
                <div class="p-6">
                    <div class="mermaid">
                        sequenceDiagram
                            participant Publisher
                            participant EventBus
                            participant Listener1
                            participant Listener2

                            Publisher->>EventBus: 发布事件
                            EventBus->>Listener1: 分发事件
                            EventBus->>Listener2: 分发事件
                            Listener1-->>EventBus: 处理事件
                            Listener2-->>EventBus: 处理事件
                    </div>
                </div>
            </div>
        </section>

        <!-- Timeline Section -->
        <section id="timeline" class="mb-20">
            <div class="flex items-center mb-8">
                <div class="w-12 h-1 bg-indigo-500 mr-4"></div>
                <h2 class="serif text-3xl font-bold">内置生命周期事件</h2>
            </div>
            
            <p class="text-gray-700 mb-8 leading-relaxed">Spring Boot 提供了一系列内置事件，这些事件与应用程序的生命周期紧密相关，帮助开发者在应用启动、运行、关闭的不同阶段执行特定逻辑。</p>
            
            <div class="relative pl-8">
                <!-- Timeline line -->
                <div class="absolute left-0 top-0 w-0.5 h-full bg-gray-200"></div>
                
                <!-- Timeline items -->
                <div class="relative mb-12 timeline-item">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <h3 class="serif text-xl font-bold mb-2">1. ApplicationStartingEvent</h3>
                        <div class="text-sm text-indigo-600 mb-3">运行开始阶段</div>
                        <p class="text-gray-700">在运行开始时发布，此时所有环境配置还未加载。这是最早可以执行自定义逻辑的时间点。</p>
                    </div>
                </div>
                
                <div class="relative mb-12 timeline-item">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <h3 class="serif text-xl font-bold mb-2">2. ApplicationEnvironmentPreparedEvent</h3>
                        <div class="text-sm text-indigo-600 mb-3">环境准备阶段</div>
                        <p class="text-gray-700">当环境信息已经准备好，但还没有创建 ApplicationContext 时发布。可以在此阶段修改环境配置。</p>
                    </div>
                </div>
                
                <div class="relative mb-12 timeline-item">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <h3 class="serif text-xl font-bold mb-2">3. ApplicationContextInitializedEvent</h3>
                        <div class="text-sm text-indigo-600 mb-3">上下文初始化</div>
                        <p class="text-gray-700">在 ApplicationContext 初始化时发布，但在 refresh 之前。可以在此阶段添加Bean定义或初始化器。</p>
                    </div>
                </div>
                
                <div class="relative mb-12 timeline-item">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <h3 class="serif text-xl font-bold mb-2">4. ApplicationPreparedEvent</h3>
                        <div class="text-sm text-indigo-600 mb-3">上下文准备完成</div>
                        <p class="text-gray-700">在上下文加载后，refresh 之前发布。此时Bean定义已加载但尚未实例化。</p>
                    </div>
                </div>
                
                <div class="relative mb-12 timeline-item">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <h3 class="serif text-xl font-bold mb-2">5. ApplicationStartedEvent</h3>
                        <div class="text-sm text-indigo-600 mb-3">应用启动阶段</div>
                        <p class="text-gray-700">在上下文刷新并启动所有相关的 ApplicationRunner 和 CommandLineRunner 之前发布。</p>
                    </div>
                </div>
                
                <div class="relative mb-12 timeline-item">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <h3 class="serif text-xl font-bold mb-2">6. ApplicationReadyEvent</h3>
                        <div class="text-sm text-indigo-600 mb-3">应用就绪</div>
                        <p class="text-gray-700">在应用启动完成后发布，表示应用已准备好接收请求。这是执行启动后逻辑的理想位置。</p>
                    </div>
                </div>
                
                <div class="relative timeline-item">
                    <div class="bg-white p-6 rounded-xl shadow-md card-hover">
                        <h3 class="serif text-xl font-bold mb-2">7. ApplicationFailedEvent</h3>
                        <div class="text-sm text-indigo-600 mb-3">启动失败</div>
                        <p class="text-gray-700">当应用启动失败时发布。可以在此事件中执行清理操作或发送通知。</p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Custom Implementation Section -->
        <section id="custom">
            <div class="flex items-center mb-8">
                <div class="w-12 h-1 bg-indigo-500 mr-4"></div>
                <h2 class="serif text-3xl font-bold">自定义事件实现</h2>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-12">
                <div>
                    <h3 class="serif text-xl font-bold mb-4">自定义事件</h3>
                    <p class="text-gray-700 mb-6 leading-relaxed">创建自定义事件只需继承 <code class="bg-gray-100 px-1 py-0.5 rounded">ApplicationEvent</code> 类，并添加所需属性。</p>
                    <div class="code-block p-4 rounded-lg mb-6">
                        <pre><code class="language-java">public class MyCustomEvent extends ApplicationEvent {
    private String message;

    public MyCustomEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}</code></pre>
                    </div>
                </div>
                <div>
                    <h3 class="serif text-xl font-bold mb-4">事件监听器</h3>
                    <p class="text-gray-700 mb-6 leading-relaxed">实现 <code class="bg-gray-100 px-1 py-0.5 rounded">ApplicationListener</code> 接口或使用 <code class="bg-gray-100 px-1 py-0.5 rounded">@EventListener</code> 注解来创建监听器。</p>
                    <div class="code-block p-4 rounded-lg">
                        <pre><code class="language-java">@Component
public class MyCustomEventListener 
    implements ApplicationListener&lt;MyCustomEvent&gt; {

    @Override
    public void onApplicationEvent(MyCustomEvent event) {
        System.out.println("Received custom event - " 
            + event.getMessage());
    }
}</code></pre>
                    </div>
                </div>
            </div>
            
            <div class="mb-12">
                <h3 class="serif text-xl font-bold mb-4">事件发布</h3>
                <p class="text-gray-700 mb-6 leading-relaxed">通过 <code class="bg-gray-100 px-1 py-0.5 rounded">ApplicationEventPublisher</code> 可以在任意组件中发布事件。</p>
                <div class="code-block p-4 rounded-lg">
                    <pre><code class="language-java">@Service
public class MyEventPublisherService {

    @Autowired
    private ApplicationEventPublisher publisher;

    public void publishEvent(String message) {
        MyCustomEvent event = new MyCustomEvent(this, message);
        publisher.publishEvent(event);
    }
}</code></pre>
                </div>
            </div>

            <!-- Advantages Section -->
            <div class="bg-indigo-50 rounded-xl p-8">
                <h3 class="serif text-2xl font-bold mb-6 text-indigo-800">事件机制的优势</h3>
                <div class="grid md:grid-cols-3 gap-6">
                    <div class="bg-white p-6 rounded-lg shadow-sm">
                        <div class="text-indigo-500 mb-3">
                            <i class="fas fa-unlink text-2xl"></i>
                        </div>
                        <h4 class="font-bold mb-2">松耦合架构</h4>
                        <p class="text-gray-700 text-sm">组件通过事件通信，无需直接引用对方，降低耦合度，增强模块化和可扩展性。</p>
                    </div>
                    <div class="bg-white p-6 rounded-lg shadow-sm">
                        <div class="text-indigo-500 mb-3">
                            <i class="fas fa-expand-arrows-alt text-2xl"></i>
                        </div>
                        <h4 class="font-bold mb-2">强大的扩展性</h4>
                        <p class="text-gray-700 text-sm">通过自定义事件和监听器，可以轻松扩展应用功能，在特定事件发生时执行操作。</p>
                    </div>
                    <div class="bg-white p-6 rounded-lg shadow-sm">
                        <div class="text-indigo-500 mb-3">
                            <i class="fas fa-life-ring text-2xl"></i>
                        </div>
                        <h4 class="font-bold mb-2">生命周期管理</h4>
                        <p class="text-gray-700 text-sm">内置的生命周期事件帮助开发者在应用启动、运行、关闭的不同阶段执行逻辑。</p>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12 px-4 sm:px-6 lg:px-8">
        <div class="max-w-5xl mx-auto">
            <div class="flex flex-col md:flex-row justify-between items-center">
                <div class="mb-4 md:mb-0">
                    <h3 class="text-xl font-bold text-white mb-2">技术小馆</h3>
                    <p class="text-gray-400">分享前沿技术，品味编程艺术</p>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="text-indigo-400 hover:text-indigo-300 transition-colors duration-300">
                        <i class="fas fa-external-link-alt mr-2"></i>访问语雀主页
                    </a>
                </div>
            </div>
            <div class="border-t border-gray-800 mt-8 pt-8 text-sm text-gray-500 text-center">
                &copy; 2023 技术小馆. 保留所有权利.
            </div>
        </div>
    </footer>

    <!-- Mermaid JS -->
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: false,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```